package com.learn.datatype.learndate.unsafe;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

/**
 * 功能：检查日期、时间格式等
 *
 * @author wsh
 * @date 2020/9/12
 */
public class DateTimeCheck {
    /**
     * 常见日期分隔符
     * - "-""/""\"：英文破折号、正斜杠、反斜杠
     * - "年月日"：中文日期单位
     */
    public static final Pattern PATTERN_SEPARATOR_DATE = Pattern.compile("[-/\\\\年月日]*");
    /**
     * 常见时间分隔符
     * - ":"：英文冒号
     * - "时分秒毫秒微秒"：中文时间单位。不支持毫秒、微秒
     */
    public static final Pattern PATTERN_SEPARATOR_TIME = Pattern.compile("[:时分秒]*");

    public static final String PATTERN_YYYYMMDD = "yyyyMMdd";
    public static final String PATTERN_HHMMSS = "HHmmss";
    public static final String PATTERN_YYYYMMDD_HHMMSS = "yyyyMMdd HHmmss";

    /**
     * 功能：判断是否有效日期时间
     * - 支持常见的日期分隔符（-/\）
     * - 支持中文时间单位（年月日）
     * - 支持分隔符混用，如 2020-01/01、2020年01-01
     * - 严谨地验证日期，比如输入 2007/02/29 就是错误的（2 月不可能有29 号）
     *
     * @param str
     * @return
     * @author wsh
     * @date 2020/9/11
     */
    public static boolean isValidDateTime(String str) {
        boolean convertSuccess = true;

        // 优先去除日期
        str = deleteDateSeparator(str);
        str = deleteTimeSeparator(str);

        try {
            SimpleDateFormat format = new SimpleDateFormat(PATTERN_YYYYMMDD_HHMMSS);
            // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }

        return convertSuccess;
    }

    /**
     * 功能：判断是否有效日期（可以识别常用的日期分隔符，如-/\，还支持中文日期单位）
     *
     * @param str
     * @return
     * @author wsh
     * @date 2020/9/11
     */
    public static boolean isValidDate(String str) {
        boolean convertSuccess = true;

        // 优先去除日期
        str = deleteDateSeparator(str);

        try {
            SimpleDateFormat format = new SimpleDateFormat(PATTERN_YYYYMMDD);
            // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }

        return convertSuccess;
    }

    /**
     * 功能：判断是否有效时间
     *
     * @param str
     * @return
     * @author wsh
     * @date 2020/9/11
     */
    public static boolean isValidTime(String str) {
        boolean convertSuccess = true;

        // 优先去除日期
        str = deleteTimeSeparator(str);

        try {
            SimpleDateFormat format = new SimpleDateFormat(PATTERN_HHMMSS);
            // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }

        return convertSuccess;
    }

    /**
     * 功能：去除日期分隔符
     *
     * @param str
     * @return
     * @author wsh
     * @date 2020/9/11
     */
    private static String deleteDateSeparator(String str) {
        return PATTERN_SEPARATOR_DATE.matcher(str).replaceAll("");
    }

    /**
     * 功能：去除时间分隔符
     *
     * @param str
     * @return
     * @author wsh
     * @date 2020/9/11
     */
    private static String deleteTimeSeparator(String str) {
        return PATTERN_SEPARATOR_TIME.matcher(str).replaceAll("");
    }

    public static void main(String[] args) {
        System.out.println(isValidDateTime("2020-01-01 11:15:00"));
        System.out.println(isValidDateTime("2020年01月01日 01时02分03秒"));
        System.out.println(isValidDate("2020/01/01"));
        System.out.println(isValidDate("2020-01/01"));
        System.out.println(isValidDate("2020年01-01"));
        System.out.println(isValidTime("11:15:00"));
        System.out.println(isValidTime("11时15:00"));
    }
}
